﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Xml;
using Newtonsoft.Json;

namespace curbside.Extensions
{
    public static class XmlExtension
    {
        #region XmlDocument Extensions

        public static XDocument ToXDocument(this XmlDocument document)
        {
            using (XmlNodeReader reader = new XmlNodeReader(document))
            {
                return XDocument.Load(reader, LoadOptions.None);
            }
        }

        public static void RemoveComment(this XmlDocument document)
        {
            XmlElement xmlElement = document.DocumentElement;
            RemoveComment(xmlElement.ChildNodes);
        }

        #endregion

        #region XmlNode Extensions

        public static string ToJson(this XmlNode node)
        {
            return JsonConvert.SerializeXmlNode(node);
        }

        public static string ToJson(this XmlNode node, Newtonsoft.Json.Formatting formatting)
        {
            return JsonConvert.SerializeXmlNode(node, formatting);
        }

        public static string ToJson(this XmlNode node, Newtonsoft.Json.Formatting formatting, bool omitRootObject)
        {
            return JsonConvert.SerializeXmlNode(node, formatting, omitRootObject);
        }

        #endregion

        #region XNode Extensions

        public static string ToJson(this XNode node)
        {
            return JsonConvert.SerializeXNode(node);
        }

        public static string ToJson(this XNode node, Newtonsoft.Json.Formatting formatting)
        {
            return JsonConvert.SerializeXNode(node, formatting);
        }

        public static string ToJson(this XNode node, Newtonsoft.Json.Formatting formatting, bool omitRootObject)
        {
            return JsonConvert.SerializeXNode(node, formatting, omitRootObject);
        }

        #endregion

        #region XElement Extensions

        public static XElement StripNameSpace(this XElement root)
        {
            return new XElement(
                root.Name.LocalName,
                root.HasElements ?
                    root.Elements().Select(el => StripNameSpace(el)) :
                    (object)root.Value
            );
        }

        #endregion

        #region Private method

        private static void RemoveComment(XmlNodeList nodes)
        {
            for (int i = 0; i < nodes.Count; i++)
            {
                var item = nodes[i];

                if (item.NodeType == XmlNodeType.Comment)
                {
                    item.ParentNode.RemoveChild(item);
                    i--;
                }
                else if (item.ChildNodes.Count > 0)
                {
                    RemoveComment(item.ChildNodes);
                }
            }
        }

        #endregion
    }
}
